package com.smartpro.mis.modular.business.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.smartpro.mis.core.base.controller.BaseController;
import com.smartpro.mis.modular.business.apiEntity.OrderExportEntity;
import com.smartpro.mis.modular.business.neo4jEntity.*;
import com.smartpro.mis.modular.business.service.*;
import com.smartpro.mis.modular.system.dao.*;
import com.smartpro.mis.modular.system.model.*;
import com.smartpro.mis.rest.common.utils.ExcelUtil;
import com.smartpro.mis.rest.modular.auth.controller.dto.ResponseBean;
import com.smartpro.mis.rest.modular.auth.util.JwtTokenUtil;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.neo4j.graphdb.Entity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.ui.Model;
import org.springframework.beans.factory.annotation.Autowired;
//import com.smartpro.mis.core.log.LogObjectHolder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 订单控制器
 *
 * @author Mengiy
 * @Date 2019-05-07 21:49:28
 */
@RestController
@RequestMapping("/api/service/orders")
public class OrdersController extends BaseController {

	@Autowired
	private IOrdersService ordersService;
	@Autowired
	private IUserService userService;
	@Autowired
	private IDistributorService distributorService;
	@Autowired
	private IProductService productService;

	@Autowired
	private IPriceService priceService;

	@Autowired
	private IGroupBuyService groupBuyService;

	@Autowired
	private IPerformanceService performanceService;

	@Autowired
	private IMessageService messageService;

	@Autowired
	private ClickDistributorRelationRepository clickDistributorRelationRepository;

	@Autowired
	private GroupBuyRelationRepository groupBuyRelationRepository;

	@Autowired
	private BuyNotPayRelationRepository buyNotPayRelationRepository;

	@Autowired
	private ApplyRefundRelationRepository applyRefundRelationRepository;

	@Autowired
	private RefundFinishRelationRepository refundFinishRelationRepository;

	@Autowired
	private DealFinishRelationRepository dealFinishRelationRepository;

	@Autowired
	private DistributorProtectRelationRepository distributorProtectRelationRepository;

	@Autowired
	private DistributorExpireRelationRepository distributorExpireRelationRepository;

	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	/**
	 * 获取订单列表
	 */
	@RequestMapping(value = "/list")
	@ResponseBody
	@RequiresAuthentication
	public Object list(String condition) {
		return ordersService.selectList(null);
	}

	/**
	 * 查询所有订单
	 */
	@ApiOperation(value = "查询所有订单", notes = "用户登录状态，请求头包含token")
	@RequestMapping(value = "/getOrders", method = RequestMethod.GET)
	@ResponseBody
	@RequiresAuthentication
	public Object getOrders() {
		return new ResponseBean(200, "query success", ordersService.selectList(null));
	}

	/**
	 * 分页查询所有订单
	 */
	@ApiOperation(value = "分页查询所有订单", notes = "用户登录状态，请求头包含token")
	@RequestMapping(value = "/getOrdersByPage", method = RequestMethod.POST)
	@ApiImplicitParam(name = "pageJSON", value = "包含字段：起始页: start,每页的条数: num", required = true, dataType = "JSONObject")
	@ResponseBody
	@RequiresAuthentication
	public Object getOrdersByPage(@RequestBody JSONObject pageJSON) {
		int start = pageJSON.getInteger("start");
		int num = pageJSON.getInteger("num");
		return new ResponseBean(200, "query success", ordersService.selectListByPage(start, num));
	}

	/**
	 * 多条件查询订单
	 */
	@ApiOperation(value = "多条件查询订单", notes = "多条件筛选订单")
	@ApiImplicitParam(name = "params", value = "json格式查询条件", required = true, dataType = "Map")
	@RequestMapping(value = "/mulQueryOrders", method = RequestMethod.POST)
	@ResponseBody
	@RequiresAuthentication
	public Object mulQueryOrders(@RequestBody Map<String, Object> params) {
		JSONObject result = new JSONObject();
		try {
			result.put("code", 200);
			result.put("message", "操作成功");
			int start = (null != params.get("start")) ? (Integer) params.get("start") : 0;
			int num = (null != params.get("num")) ? (Integer) params.get("num") : 0;
			Map<String, Object> queryParams = new HashMap<String, Object>();
			for (String key : params.keySet()) {
				if (params.get(key) != null && !"".equals(params.get(key))) {
					queryParams.put(key, params.get(key));
				}
			}
			result.put("data", ordersService.selectByMap(queryParams));
		} catch (Exception e) {
			result.put("code", 400);
			result.put("message", e.getMessage());
			result.put("data", null);
		}
		return result;
	}

	/**
	 * 根据时间段查询订单列表
	 */
	@ApiOperation(value = "查看订单", notes = "根据时间段查询订单列表")
	@ApiImplicitParam(name = "params", value = "json格式查询条件，包含元素:startTime,endTime,格式:yyyy-MM-dd HH:mm:SS,若做分页查询,请传整数值start与num，并保证num值大于0", required = true, dataType = "jsonObject")
	@RequestMapping(value = "/getAllOrders", method = RequestMethod.POST)
	@ResponseBody
	@RequiresAuthentication
	public Object getAllOrders(@RequestBody JSONObject params) {
		JSONObject result = new JSONObject();
		String startTime = params.getString("startTime");
		String endTime = params.getString("endTime");
		int start = (null != params.get("start")) ? params.getInteger("start") : 0;
		int num = (null != params.get("num")) ? params.getInteger("num") : 0;
		List<Orders> ordersList = ordersService.selectOrdersList(startTime, endTime, start, num);
		try {
			result.put("code", 200);
			result.put("message", "操作成功");
			result.put("data", JSONObject.toJSON(ordersList));
		} catch (Exception e) {
			result.put("code", 400);
			result.put("message", e.getMessage());
			result.put("data", null);
		}
		return result;
	}

	/**
	 * 未处理退款订单数量
	 */
	@ApiOperation(value = "未处理退款订单数量")
	@RequestMapping(value = "/countOfRefund")
	@ResponseBody
	@RequiresAuthentication
	public Object countOfRefund() {
		EntityWrapper<Orders> wrapper = new EntityWrapper<Orders>();
		wrapper.where("isValid = 0").where("refundStatus=0");
		return new ResponseBean(200, "query success", ordersService.selectCount(wrapper));
	}

	/**
	 * 待邮寄订单数量
	 */
	@ApiOperation(value = "待邮寄订单数量")
	@RequestMapping(value = "/countOfPost")
	@ResponseBody
	@RequiresAuthentication
	public Object countOfPost() {
		EntityWrapper<Orders> wrapper = new EntityWrapper<Orders>();
		wrapper.where("isValid = 0").where("postStatus=2");
		return new ResponseBean(200, "query success", ordersService.selectCount(wrapper));
	}

	/**
	 * 无效订单数量
	 */
	@ApiOperation(value = "无效订单数量")
	@RequestMapping(value = "/countOfInvalid")
	@ResponseBody
	@RequiresAuthentication
	public Object countOfInvalid() {
		EntityWrapper<Orders> wrapper = new EntityWrapper<Orders>();
		wrapper.where("isValid = 1");
		return new ResponseBean(200, "query success", ordersService.selectCount(wrapper));
	}

	/**
	 * 订单导出
	 */
	@ApiOperation(value = "订单导出", notes = "根据时间段查询订单列表并导出excel,参数包括：开始时间、结束时间、合作机构名称")
	@ApiImplicitParam(name = "params", value = "json格式查询条件，包含元素:startTime,endTime,belongToCompany,若做分页查询,请传整数值start与num，并保证num值大于0", required = true, dataType = "Map")
	@RequestMapping(value = "/exportOrder", method = RequestMethod.POST)
	@ResponseBody
	@RequiresAuthentication
	public void exportOrder(@RequestBody Map params, HttpServletResponse response) {
		String startTime = (String) params.get("startTime");
		String endTime = (String) params.get("endTime");
		String belongToCompany = (String) params.get("belongToCompany");
		int start = (null != params.get("start")) ? (Integer) params.get("start") : 0;
		int num = (null != params.get("num")) ? (Integer) params.get("num") : 0;
		List<Orders> ordersList = ordersService.getOrdersListByCompany(startTime, endTime, belongToCompany, start, num);
		List<OrderExportEntity> orderExportEntityList = new ArrayList<>();
		for (Orders o : ordersList) {
			OrderExportEntity orderExportEntity = new OrderExportEntity();
			orderExportEntity.setAddress(o.getAddress());
			orderExportEntity.setBelongToCompany(o.getBelongToCompany());
			orderExportEntity.setChildName(o.getChildName());
			orderExportEntity.setGroupPrice(o.getGroupPrice());
			orderExportEntity.setCreateTime(o.getCreateTime());
			orderExportEntity.setInstantPrice(o.getInstantPrice());
			orderExportEntity.setGroupPrice(o.getGroupPrice());
			orderExportEntity.setLeaderPrice(o.getLeaderPrice());
			orderExportEntity.setMobile(o.getMobile());
			orderExportEntity.setNickName(o.getNickName());
			orderExportEntity.setNumberOfProduct(o.getNumberOfProduct());
			orderExportEntity.setTotalAmount(o.getTotalAmount());
			orderExportEntity.setOrderNumber(o.getOrderNumber());
			orderExportEntityList.add(orderExportEntity);
		}

		ExcelUtil.exportExcel(orderExportEntityList, "订单明细", "sheet1", OrderExportEntity.class,
				new SimpleDateFormat("yyyyMMddHHmmSS").format(new Date()) + ".xls", response);
	}

	/**
	 * 查询我的订单
	 */
	@ApiOperation(value = "查询我的推广订单", notes = "登录用户查询自己推广的订单")
	@RequestMapping(value = "/getMyDistributorOrders", method = RequestMethod.GET)
	@ResponseBody
	@RequiresAuthentication
	public Object getMyDistributorOrders(HttpServletRequest request) {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		String authorization = httpServletRequest.getHeader("Authorization");
		JwtTokenUtil jwt = new JwtTokenUtil();
		String username = jwt.getUsernameFromToken(authorization);
		Map<String, Object> condtion = new HashMap();
		condtion.put("wechat", username);
		User user = this.userService.selectByMap(condtion).get(0);
		List<Orders> orderList = ordersService.getMyDistributorOrderList(user.getUserID());

		List<JSONObject> orders = new ArrayList<>();
		for (Orders obj : orderList) {
			JSONObject json = (JSONObject) JSONObject.toJSON(obj);
//            JSONObject json = new JSONObject();
			json.put("orderID", obj.getOrderID());
			int productID = obj.getProductID();
			json.put("productID", productID);
			Product product = productService.selectById(productID);
			json.put("smallPicture", product.getSmallPicture());
			json.put("bigPicture", product.getBigPicture());
			json.put("name", product.getName());
			json.put("description", product.getDescription());
			// 订单表未与价格策略表关联，无法查询商品规格
			// 获取商品的所有价格
//            Map<String,Object> pmap = new HashMap<>();
//            pmap.put("productID",product.getProductID());
//            List<Price> prices = this.priceService.selectByMap(pmap);
//            List<JSONObject> priceList = new ArrayList<>();
//            json.put("priceList",JSONArray.parseArray(JSON.toJSONString(priceList)));

//    增加当前订单购买的价格规格信息
			if (obj.getPriceID() > 0) {
				Price price = this.priceService.selectById(obj.getPriceID());
				json.put("specList", price.getSpecList());
			}
			BigDecimal price = null;
			if (null != obj.getInstantPrice()) {
				price = obj.getInstantPrice();
			} else if (null != obj.getLeaderPrice()) {
				price = obj.getLeaderPrice();
			} else if (null != obj.getGroupPrice()) {
				price = obj.getGroupPrice();
			}
			json.put("buyPrice", price);
			json.put("numberOfProduct", obj.getNumberOfProduct());
			json.put("inTotal", obj.getTotalAmount());
			json.put("purchaseTime", obj.getCreateTime());
			orders.add(json);
		}

		return new ResponseBean(200, "operation success", JSONObject.toJSON(orders));

	}

	/**
	 * 查询我的订单
	 */
	@ApiOperation(value = "查询我的订单", notes = "登录用户查询订单")
	@RequestMapping(value = "/getMyOrders", method = RequestMethod.GET)
	@ResponseBody
	@RequiresAuthentication
	public Object getMyOrders(HttpServletRequest request) {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		String authorization = httpServletRequest.getHeader("Authorization");
		JwtTokenUtil jwt = new JwtTokenUtil();
		String username = jwt.getUsernameFromToken(authorization);
		Map<String, Object> condtion = new HashMap();
		condtion.put("wechat", username);
		User user = this.userService.selectByMap(condtion).get(0);
		int userID = user.getUserID();
		Map condition = new HashMap();
		condition.put("userID", userID);
		List<Orders> orderList = ordersService.selectByMap(condition);
		List<JSONObject> orders = new ArrayList<>();
		for (Orders obj : orderList) {
			JSONObject json = (JSONObject) JSONObject.toJSON(obj);
//            JSONObject json = new JSONObject();
			json.put("orderID", obj.getOrderID());
			int productID = obj.getProductID();
			json.put("productID", productID);
			Product product = productService.selectById(productID);
			json.put("smallPicture", product.getSmallPicture());
			json.put("bigPicture", product.getBigPicture());
			json.put("name", product.getName());
			json.put("description", product.getDescription());
			// 订单表未与价格策略表关联，无法查询商品规格
			// 获取商品的所有价格
//            Map<String,Object> pmap = new HashMap<>();
//            pmap.put("productID",product.getProductID());
//            List<Price> prices = this.priceService.selectByMap(pmap);
//            List<JSONObject> priceList = new ArrayList<>();
//            json.put("priceList",JSONArray.parseArray(JSON.toJSONString(priceList)));

//    增加当前订单购买的价格规格信息
			if (obj.getPriceID() > 0) {
				Price price = this.priceService.selectById(obj.getPriceID());
				json.put("specList", price.getSpecList());
			}
			BigDecimal price = null;
			if (null != obj.getInstantPrice()) {
				price = obj.getInstantPrice();
			} else if (null != obj.getLeaderPrice()) {
				price = obj.getLeaderPrice();
			} else if (null != obj.getGroupPrice()) {
				price = obj.getGroupPrice();
			}
			json.put("buyPrice", price);
			json.put("numberOfProduct", obj.getNumberOfProduct());
			json.put("inTotal", obj.getTotalAmount());
			json.put("purchaseTime", obj.getCreateTime());
			orders.add(json);
		}

		return new ResponseBean(200, "operation success", JSONObject.toJSON(orders));

	}

	/**
	 * 根据条件查询我的订单
	 */
	@ApiOperation(value = "条件查询我的订单", notes = "登录用户自定义条件查询订单")
	@ApiImplicitParam(name = "params", value = "订单的查询条件：包括订单退款状态refundStatus,订单邮寄状态postStatus,订单有效状态isValid等元素(可选)")
	@RequestMapping(value = "/getMyOrdersByParams", method = RequestMethod.POST)
	@ResponseBody
	@RequiresAuthentication
	public Object getMyOrdersByParams(HttpServletRequest request, @RequestBody JSONObject params) {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		String authorization = httpServletRequest.getHeader("Authorization");
		JwtTokenUtil jwt = new JwtTokenUtil();
		String username = jwt.getUsernameFromToken(authorization);
		Map<String, Object> condtion = new HashMap();
		condtion.put("wechat", username);
		User user = this.userService.selectByMap(condtion).get(0);
		int userID = user.getUserID();
		Map condition = JSONObject.parseObject(params.toJSONString(), Map.class);
		condition.put("userID", userID);
		List<Orders> orderList = ordersService.selectByMap(condition);
		List<JSONObject> orders = new ArrayList<>();
		for (Orders obj : orderList) {
//            JSONObject json = new JSONObject();
			JSONObject json = (JSONObject) JSONObject.toJSON(obj);
			json.put("orderID", obj.getOrderID());
			int productID = obj.getProductID();
			json.put("productID", productID);
			Product product = productService.selectById(productID);
			json.put("smallPicture", product.getSmallPicture());
			json.put("bigPicture", product.getBigPicture());
			json.put("name", product.getName());
			json.put("description", product.getDescription());
			// 订单表未与价格策略表关联，无法查询商品规格

			// 获取商品的所有价格
			/**
			 * Map<String,Object> pmap = new HashMap<>();
			 * pmap.put("productID",product.getProductID()); List<Price> prices =
			 * this.priceService.selectByMap(pmap); List<JSONObject> priceList = new
			 * ArrayList<>();
			 * json.put("priceList",JSONArray.parseArray(JSON.toJSONString(priceList)));
			 * 
			 * Map<String,Object> pmap = new HashMap<>();
			 * pmap.put("productID",product.getProductID()); List<Price> prices =
			 * this.priceService.selectByMap(pmap); List<JSONObject> priceList = new
			 * ArrayList<>(); for(Price price:prices){ JSONObject pjson = new JSONObject();
			 * pjson.put("specList",price.getSpecList());
			 * pjson.put("instantPrice",price.getInstantPrice());
			 * pjson.put("groupPrice",price.getGroupPrice()); JSONArray personalList =
			 * JSONArray.parseArray(price.getPersonalList()); BigDecimal income = null;
			 * //标号标记要跳出的循环 outterLoop: for(int i=0;i<personalList.size();i++){ JSONObject o
			 * = personalList.getJSONObject(i); for(String s:o.keySet()){
			 * if(s.contains(userID+"")){ income = o.getBigDecimal(s); break outterLoop; //
			 * 会跳出标号标记的那个循环 } } } pjson.put("income",income); priceList.add(pjson);
			 * 
			 * } json.put("price", priceList);
			 **/
			/*
			 * // 增加当前订单购买的价格规格信息 if(obj.getPriceID()>0){ Price price =
			 * this.priceService.selectById(obj.getPriceID());
			 * json.put("specList",price.getSpecList()); }
			 * json.put("price",obj.getInstantPrice());
			 * json.put("numberOfProduct",obj.getNumberOfProduct());
			 * json.put("inTotal",obj.getTotalAmount());
			 * json.put("purchaseTime",obj.getCreateTime());
			 */

			// 获取价格
			if (obj.getPriceID() > 0) {
				Price price = this.priceService.selectById(obj.getPriceID());
				json.put("specList", price.getSpecList());
			}
			BigDecimal price = null;
			if (null != obj.getInstantPrice()) {
				price = obj.getInstantPrice();
			} else if (null != obj.getLeaderPrice()) {
				price = obj.getLeaderPrice();
			} else if (null != obj.getGroupPrice()) {
				price = obj.getGroupPrice();
			}
			json.put("buyPrice", price);
			json.put("numberOfProduct", obj.getNumberOfProduct());
			json.put("inTotal", obj.getTotalAmount());
			json.put("purchaseTime", obj.getCreateTime());
			orders.add(json);
		}

		return new ResponseBean(200, "operation success", JSONObject.toJSON(orders));

	}
    /**

    /**
     * 新增订单
     */
    @RequestMapping(value = "/add")
    @ResponseBody
    @RequiresAuthentication
    public Object add(Orders orders) {
        ordersService.insert(orders);
        return SUCCESS_TIP;
    }

    /**
     * 购买商品
     */
    @ApiOperation(value = "购买商品",notes = "登录用户购买商品，1. 商品购买接口的输入参数中应该如果是团购，且没有团购id，那就是团长购买的并可以开团;" +
            "2. 商品购买接口的输入参数中如果是团购，且有团购id，那就是团员购买的;3.  商品购买接口的输入参数中如果不是团购，那就是直接购买的")
    @ApiImplicitParam(name = "orders",value = "JSON包含元素：productID,groupBuy,distributorID,groupBuyID,priceID,leaderPrice,instancePrice," +
            "groupPrice,purchaseNumber,inTotal,childName,childGender,mobile,address,comments",dataType = "JSONObject")
    @RequestMapping(value = "/postPurchase",method = RequestMethod.POST)
    @ResponseBody
    @RequiresAuthentication
    @Transactional
    public Object postPurchase(HttpServletRequest request,@RequestBody JSONObject obj) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String authorization = httpServletRequest.getHeader("Authorization");
        JwtTokenUtil jwt = new JwtTokenUtil();
        String username = jwt.getUsernameFromToken(authorization);
        Map<String,Object> condtion = new HashMap();
        condtion.put("wechat",username);
        User user = this.userService.selectByMap(condtion).get(0);
        int productID = obj.getInteger("productID");
        int priceID = obj.getInteger("priceID");
        Product product = this.productService.selectById(productID);
        Price price = this.priceService.selectById(priceID);
        Orders orders = new Orders();
        orders.setPriceID(priceID);
        orders.setProductID(productID);
        orders.setName(product.getName());
        orders.setIsValid(0);
        int ispost = 0;
        if(product.getIsPost() == 0) {//0 是需要邮寄的  需要邮寄的商品将订单的邮寄状态设置为未邮寄
        	ispost = 2;
        }
        orders.setPostStatus(ispost);
        orders.setCreateTime(sdf.format(new Date()));
        orders.setUserID(user.getUserID());
        orders.setChildName(obj.getString("childName"));
        orders.setMobile(obj.getString("mobile"));
        orders.setNickName(user.getNickName());
        orders.setAddress(obj.getString("address"));
        orders.setGroupPrice(obj.getBigDecimal("groupPrice"));
        orders.setLeaderPrice(obj.getBigDecimal("leaderPrice"));
        orders.setNumberOfProduct(obj.getInteger("purchaseNumber"));
        orders.setInstantPrice(obj.getBigDecimal("instancePrice"));
        orders.setTotalAmount(obj.getBigDecimal("inTotal"));
        orders.setRefundStatus(3);
        //neo4j新增购买未付款关系
        this.buyNotPayRelationRepository.save(new BuyNotPayRelationship(sdf.format(new Date()),new N4jUser(user.getUserID()),new N4jProduct(productID)));


        //若该用户没有设置推广员并且前端没传推广员ID，则设为虚拟推广员的团购
        int distID = -1;
        //是团购但没有团购ID，说明是团长购买，此时需要将信息插入团购表
        if(obj.containsKey("groupBuy") && !obj.containsKey("groupBuyID")){
            GroupBuy groupBuy = new GroupBuy();
            groupBuy.setCreateTime(sdf.format(new Date()));
            groupBuy.setGroupPrice(obj.getBigDecimal("groupPrice"));
            groupBuy.setInstantPrice(obj.getBigDecimal("instancePrice"));
            groupBuy.setLeaderPrice(obj.getBigDecimal("leaderPrice"));
            groupBuy.setNumberOfMember(null != obj.get("numberOfMember")?obj.getInteger("numberOfMember"):null);
            groupBuy.setProductID(productID);
            groupBuy.setSpecList(price.getSpecList());
            groupBuy.setDuration(null != obj.get("duration")?obj.getInteger("duration"):null);
            groupBuy.setIsMultiple(null != obj.get("isMultiple")?obj.getInteger("isMultiple"):null);

            int leaderID = user.getUserID();
            groupBuy.setLeaderID(leaderID);
            //memberlist需要有参团时间
            List<JSONObject> memberList = new ArrayList<>();
            JSONObject memberJSON = new JSONObject();
            memberJSON.put("userID", user.getUserID());
            memberJSON.put("groupBuyTime", sdf.format(new Date()));
            memberList.add(memberJSON);
            groupBuy.setMemberList(JSONObject.toJSONString(memberList));
            //从neo4j获取推广者ID
            // todo  ....
            try {

                try {
                    //若该团购用户没有设置推广员，则从参数里获取，作为该用户的推广员,
//                    distID = this.clickDistributorRelationRepository.getDistributorID(leaderID);
					DistributorExpireRelationship distributorExpireRelationship = this.distributorExpireRelationRepository
							.findExpireRelationByN4jUser(new N4jUser(leaderID));
					if ((new Date().getTime() - sdf.parse(distributorExpireRelationship.getCreateTime()).getTime()) / 24 * 60 * 60
							- distributorExpireRelationship.getExpireTime() <= 0) {
						// 未过期
						distID = distributorExpireRelationship.getN4jDistributor().getDistributorID();
					} else {
						// 过期了，重新绑定虚拟推广员
						this.distributorExpireRelationRepository.updateRelationById(distributorExpireRelationship.getId(),
								sdf.format(new Date()), 0, new N4jDistributor(distID), new N4jUser(leaderID));
						if (null != obj.get("distributorID")) {
							distID = obj.getInteger("distributorID");
						}
					}

				} catch (Exception e2) {
					if (null != obj.get("distributorID")) {
						distID = obj.getInteger("distributorID");
					}
				}
				// todo 若参数没有传递推广员ID，并且当前用户并未在系统设置过推广员，则设置一个虚拟的推广员，-1
				groupBuy.setDistributorID(distID);
				this.groupBuyService.insert(groupBuy);
				orders.setGroupBuyID(groupBuy.getGroupBuyID());

			} catch (Exception e) {
				// 增加团购需要先为当前用户设置推广员
				return new ResponseBean(400,
						"system cannot set distributor for this groupBuy, please add distributor for the current user first.",
						groupBuy);
			}

		} else if (obj.containsKey("groupBuy") && obj.containsKey("groupBuyID")) {
			GroupBuy groupBuy = this.groupBuyService.selectById(obj.getInteger("groupBuyID"));
			if (null != groupBuy) {
//                StringBuilder memberList = new StringBuilder(groupBuy.getMemberList());
				List<JSONObject> memberList = JSONObject.parseArray(groupBuy.getMemberList(), JSONObject.class);
				JSONObject memberJSON = new JSONObject();
				memberJSON.put("userID", user.getUserID());
				memberJSON.put("groupBuyTime", sdf.format(new Date()));
				memberList.add(memberJSON);
				groupBuy.setMemberList(JSONObject.toJSONString(memberList));

				groupBuy.setMemberList(JSONObject.toJSONString(memberList));
				groupBuy.setModifyTime(sdf.format(new Date()));

				groupBuyService.updateById(groupBuy);
				// 新增neo4j的团购关系
				int leaderID = groupBuy.getLeaderID();
				GroupBuyRelationship groupBuyRelationship = new GroupBuyRelationship(sdf.format(new Date()),
						new N4jUser(leaderID), new N4jUser(user.getUserID()));
				groupBuyRelationRepository.save(groupBuyRelationship);
			}

		}
		// 不是团购，不操作团购表，直接新增订单表即可
		ordersService.insert(orders);

		// 给推广员发送消息，通知有此订单
		// 发消息
		try {
			Message message = new Message();
			message.setReceiverID(distID);
			message.setCreateTime(sdf.format(new Date()));
			message.setMessageType(3);
			// 0 未读 1 已读
			message.setIsRead(0);
			// 发送者为-1，表示是系统通知消息
			message.setSenderID(-1);
			this.messageService.insert(message);
		} catch (Exception e3) {
			System.out.println("消息提醒失败!");
			System.err.println(e3.getMessage());
		}

		/**
		 * 前端产生购买结果链接
		 */
		return new ResponseBean(200, "submit success", orders);
	}

	/**
	 * 删除订单
	 */
	@ApiOperation(value = "删除订单", notes = "需要订单编号")
	@RequestMapping(value = "/delete/{ordersId}", method = RequestMethod.GET)
	@ResponseBody
	@RequiresAuthentication
	public Object delete(@PathVariable Integer ordersId) {
		ordersService.deleteById(ordersId);
		return new ResponseBean(200, "delete success", null);
	}

	/**
	 * 修改订单
	 */
	@ApiOperation(value = "更新订单", notes = "需要带有订单编号的订单JSON")
	@RequestMapping(value = "/update", method = RequestMethod.POST)
	@ResponseBody
	@RequiresAuthentication
	public Object update(@RequestBody Orders orders) {
		ordersService.updateById(orders);
		return new ResponseBean(200, "update success", orders);
	}

	/**
	 * 设置订单退款状态
	 */
	@ApiOperation(value = "设置订单退款状态", notes = "需要参数：订单ID,退款状态")
	@ApiImplicitParam(name = "jsonData", value = "包含元素：orderID,refundStatus", dataType = "JSONObject")
	@RequestMapping(value = "/setRefundStatus", method = RequestMethod.POST)
	@ResponseBody
	@RequiresAuthentication
	public Object setRefundStatus(HttpServletRequest request, @RequestBody JSONObject jsonObject) {
		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		String authorization = httpServletRequest.getHeader("Authorization");
		JwtTokenUtil jwt = new JwtTokenUtil();
		String username = jwt.getUsernameFromToken(authorization);
		Map<String, Object> condtion = new HashMap();
		condtion.put("wechat", username);
		User user = this.userService.selectByMap(condtion).get(0);
		int orderID = jsonObject.getInteger("orderID");
		int refundStatus = jsonObject.getInteger("refundStatus");
		Orders orders = ordersService.selectById(orderID);
		orders.setRefundStatus(refundStatus);
		ordersService.updateById(orders);
		int productID = orders.getProductID();
		// 判断该商品是否可退，是否超出退款最迟时刻 getCanRefund ==1 则可以退款
		Product productOrder = this.productService.selectById(productID);
		try {
			if (productOrder.getCanRefund() == 1) {
				if (null != productOrder.getRefundDays()) {
					Date date = sdf.parse(orders.getCreateTime());
					Calendar cl = Calendar.getInstance();
					cl.setTime(date);
					cl.set(Calendar.DATE, cl.get(Calendar.DATE) + productOrder.getRefundDays());
					if (new Date().getTime() - cl.getTimeInMillis() > 0) {
						return new ResponseBean(400, "this order had past the last refund time, cannot refund.", productOrder);
					}

				} else if (new Date().after(sdf.parse(productOrder.getLatestRefundTime()))) {
					return new ResponseBean(400, "this order had past the last refund time, cannot refund.", productOrder);
				}
			}
		} catch (ParseException e) {
			return new ResponseBean(500, "inner error.", e.getMessage());
		}
		Price price = this.priceService.selectById(orders.getPriceID());
		JSONArray personalList = JSONArray.parseArray(price.getPersonalList());
		BigDecimal income = null;
		// 标号标记要跳出的循环
		outterLoop: for (int i = 0; i < personalList.size(); i++) {
			JSONObject o = personalList.getJSONObject(i);
			for (String s : o.keySet()) {
				if (s.contains(user.getUserID() + "")) {
					income = o.getBigDecimal(s);
					break outterLoop; // 会跳出标号标记的那个循环
				}
			}
		}
		BigDecimal totalIncome = null;
		if (null != income) {
			totalIncome = income.multiply(BigDecimal.valueOf(orders.getNumberOfProduct()));
		}

//        退款状态影响neo4j实体关系和推广员绩效,0申请退款，1退款完成，2无需退款
		Performance performance = new Performance();
		performance.setCreateTime(sdf.format(new Date()));
		performance.setOrderID(orderID);
		performance.setTotalAmount(orders.getTotalAmount());
		N4jUser n4jUser = new N4jUser(user.getUserID());
		N4jProduct n4jProduct = new N4jProduct(orders.getProductID());
		if (refundStatus == 0) {
			ApplyRefundRelationship applyRefundRelationship = new ApplyRefundRelationship(sdf.format(new Date()), n4jUser,
					n4jProduct);
			applyRefundRelationRepository.save(applyRefundRelationship);
		} else if (refundStatus == 1) {
			RefundFinishRelationship refundFinishRelationship = new RefundFinishRelationship(sdf.format(new Date()), n4jUser,
					n4jProduct);
			refundFinishRelationRepository.save(refundFinishRelationship);
			// 查询绩效表，若有该用户的订单则扣除该绩效,删除该绩效记录
			Map<String, Object> map = new HashMap<>();
			map.put("orderID", orderID);
			map.put("distributorID", user.getUserID());
			List<Performance> plist = performanceService.selectByMap(map);
			if (plist.size() > 0) {
				performanceService.deleteById(plist.get(0).getIncomeID());
			}

		} else if (refundStatus == 2) {
			// 交易完成
			DealFinishRelationship dealFinishRelationship = new DealFinishRelationship(sdf.format(new Date()), n4jUser,
					n4jProduct);
			dealFinishRelationRepository.save(dealFinishRelationship);
			DistributorExpireRelationship distributorExpireRelationship = this.distributorExpireRelationRepository
					.findExpireRelationByN4jUser(n4jUser);
			try {
				int days = (int) ((new Date().getTime() - sdf.parse(distributorExpireRelationship.getCreateTime()).getTime())
						/ (1000 * 3600 * 24));
				// 没有过期
				if (days <= distributorExpireRelationship.getExpireTime()) {
					// if(1==1) {
					int distributorID = distributorExpireRelationship.getN4jDistributor().getDistributorID();
					// int distributorID = 2;
					User distributor = this.userService.selectById(distributorID);
					BigDecimal incomeD = null;
					// 标号标记要跳出的循环
					outterLoop: for (int i = 0; i < personalList.size(); i++) {
						JSONObject o = personalList.getJSONObject(i);
						String s = o.getString("distributorIDList");
						// for(String s:o.keySet()){
						if (s.contains(distributor.getMobile() + "")) {
							incomeD = o.getBigDecimal("income");
							break outterLoop; // 会跳出标号标记的那个循环
						}
						// }
					}
					BigDecimal totalIncomeD = null;
					if (null != incomeD) {
						totalIncomeD = incomeD.multiply(BigDecimal.valueOf(orders.getNumberOfProduct()));
					}
					performance.setIncome(totalIncomeD);
					performance.setDistributorID(distributorID);
					this.performanceService.insert(performance);

				} else {
					// 过期则直接删除人与人之间关系（有效期和保护期）
					distributorExpireRelationRepository.delete(distributorExpireRelationship.getId());
					DistributorProtectRelationship distributorProtectRelationship = this.distributorProtectRelationRepository
							.findProtectRelationByN4jUser(n4jUser);
					distributorProtectRelationRepository.delete(distributorProtectRelationship.getId());
				}
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return new ResponseBean(200, "set success", JSONObject.toJSON(orders));
	}

	/**
	 * 完成订单
	 */
	@ApiOperation(value = "完成订单", notes = "需要参数：订单ID,退款状态")
	@ApiImplicitParam(name = "jsonData", value = "包含元素：orderID,refundStatus", dataType = "JSONObject")
	@RequestMapping(value = "/finishOrder", method = RequestMethod.POST)
	@ResponseBody
	@RequiresAuthentication
	public Object finishOrder(HttpServletRequest request, @RequestBody JSONObject jsonObject) {
		int orderID = jsonObject.getInteger("orderID");
		int refundStatus = jsonObject.getInteger("refundStatus");
		Orders orders = ordersService.selectById(orderID);
		orders.setRefundStatus(refundStatus);
		ordersService.updateById(orders);
		if (refundStatus == 2) {

			N4jUser n4jUser = new N4jUser(orders.getUserID());
			N4jProduct n4jProduct = new N4jProduct(orders.getProductID());
			// 交易完成
			DealFinishRelationship dealFinishRelationship = new DealFinishRelationship(sdf.format(new Date()), n4jUser,
					n4jProduct);
			dealFinishRelationRepository.save(dealFinishRelationship);
			// 检查商品是否可推广
			Product product = this.productService.selectById(orders.getProductID());
			if (!"0".equals(product.getIsDistribution())) {
				Performance performance = new Performance();
				performance.setCreateTime(sdf.format(new Date()));
				performance.setOrderID(orderID);
				BigDecimal totalIncomeD = null;
				try {
					Price price = this.priceService.selectById(orders.getPriceID());
					JSONArray personalList = JSONArray.parseArray(price.getPersonalList());
					JSONArray incomeClassList = JSONArray.parseArray(price.getIncomeClassList());
//        退款状态影响neo4j实体关系和推广员绩效,0申请退款，1退款完成，2无需退款
					int distributorID = 0;
					BigDecimal incomeD = null;
					// 检查商品购买者是否是推广员
					Distributor distributor = this.distributorService.selectById(orders.getUserID());
					if (distributor != null) {
						
						int status = distributor.getStatus();
						String levelCode = distributor.getLevelCode();
					// 判断推广员是否有效或过期
						if (status == 1) {
								distributorID = distributor.getUserID();
								for (int i = 0; i < personalList.size(); i++) {
									JSONObject o = personalList.getJSONObject(i);
									String s = o.getString("distributorIDList");
									// for(String s:o.keySet()){
									if (s.contains(orders.getMobile() + "")) {
										incomeD = o.getBigDecimal("income");
										break; // 会跳出循环
									}
								}
								BigDecimal levelIncome = new BigDecimal("0");
								for (int i = 0; i < incomeClassList.size(); i++) {
									JSONObject o = incomeClassList.getJSONObject(i);
									String s = o.getString("classID");
									// for(String s:o.keySet()){
									if (s.contains(levelCode + "")) {
										levelIncome = o.getBigDecimal("income");
										break; // 会跳出循环
									}
								}
								if (levelIncome.compareTo(incomeD) == 1)incomeD = levelIncome;
								if (null != incomeD) {
									totalIncomeD = incomeD.multiply(BigDecimal.valueOf(orders.getNumberOfProduct()));
								}
						}
					}
					if (distributorID == 0) {
						// 检查推广员是否过期
						DistributorExpireRelationship distributorExpireRelationship = this.distributorExpireRelationRepository
								.findExpireRelationByN4jUser(n4jUser);
						if (distributorExpireRelationship != null) {
							int days = (int) ((new Date().getTime()
									- sdf.parse(distributorExpireRelationship.getCreateTime()).getTime()) / (1000 * 3600 * 24));
							// 没有过期
							if (days <= distributorExpireRelationship.getExpireTime()) {
								// if(1==1) {
								distributorID = distributorExpireRelationship.getN4jDistributor().getDistributorID();
								// int distributorID = 2;
								User user = this.userService.selectById(distributorID);
								distributor = this.distributorService.selectById(distributorID);
								// 标号标记要跳出的循环
								outterLoop: for (int i = 0; i < personalList.size(); i++) {
									JSONObject o = personalList.getJSONObject(i);
									String s = o.getString("distributorIDList");
									// for(String s:o.keySet()){
									if (s.contains(user.getMobile() + "")) {
										incomeD = o.getBigDecimal("income");
										break outterLoop; // 会跳出标号标记的那个循环
									}
									// }
								}
								BigDecimal levelIncome = null;
								for (int i = 0; i < incomeClassList.size(); i++) {
									JSONObject o = incomeClassList.getJSONObject(i);
									String s = o.getString("classID");
									// for(String s:o.keySet()){
									if (s.contains(distributor.getLevelCode() + "")) {
										levelIncome = o.getBigDecimal("income");
										break; // 会跳出循环
									}
								}
								if (levelIncome.compareTo(incomeD) == 1)incomeD = levelIncome;
								if (null != incomeD) {
									totalIncomeD = incomeD.multiply(BigDecimal.valueOf(orders.getNumberOfProduct()));
								}
								

							} else {
								// 过期则直接删除人与人之间关系（有效期和保护期）
								distributorExpireRelationRepository.delete(distributorExpireRelationship.getId());
								DistributorProtectRelationship distributorProtectRelationship = this.distributorProtectRelationRepository
										.findProtectRelationByN4jUser(n4jUser);
								distributorProtectRelationRepository.delete(distributorProtectRelationship.getId());
							}
						}
					}
					performance.setTotalAmount(orders.getTotalAmount());
					performance.setIncome(totalIncomeD);
					performance.setDistributorID(distributorID);
					if (distributorID != 0)this.performanceService.insert(performance);
				} catch (ParseException e) {
					e.printStackTrace();
				}
			}
		}
		return new ResponseBean(200, "set success", JSONObject.toJSON(orders));
	}

	/**
	 * 设置订单有效状态
	 */
	@ApiOperation(value = "设置订单有效状态", notes = "需要参数：订单ID,是否有效状态")
	@ApiImplicitParam(name = "jsonData", value = "包含元素：orderID,isValid", dataType = "JSONObject")
	@RequestMapping(value = "/setValidStatus", method = RequestMethod.POST)
	@ResponseBody
	@RequiresAuthentication
	public Object setValidStatus(@RequestBody JSONObject jsonData) {
		int orderID = jsonData.getInteger("orderID");
		int isValid = jsonData.getInteger("isValid");
		Orders orders = ordersService.selectById(orderID);
		orders.setIsValid(isValid);
		ordersService.updateById(orders);
		return new ResponseBean(200, "set success", JSONObject.toJSON(orders));
	}

	/**
	 * 设置订单邮寄状态
	 */
	@ApiOperation(value = "设置订单邮寄状态", notes = "需要参数：订单ID,邮寄状态")
	@ApiImplicitParam(name = "jsonData", value = "包含元素：orderID,postStatus", dataType = "JSONObject")
	@RequestMapping(value = "/setPostStatus", method = RequestMethod.POST)
	@ResponseBody
	@RequiresAuthentication
	public Object setPostStatus(@RequestBody JSONObject jsonData) {
		int orderID = jsonData.getInteger("orderID");
		int postStatus = jsonData.getInteger("postStatus");
		Orders orders = ordersService.selectById(orderID);
		orders.setPostStatus(postStatus);
		ordersService.updateById(orders);
		return new ResponseBean(200, "set success", JSONObject.toJSON(orders));
	}

	/**
	 * 设置订单邮寄状态和有效状态
	 */
	@ApiOperation(value = "设置订单邮寄状态和有效状态", notes = "需要参数：订单ID,邮寄状态，有效状态")
	@ApiImplicitParam(name = "jsonData", value = "包含元素：orderID,postStatus,isValid", dataType = "JSONObject")
	@RequestMapping(value = "/setOrderStatus", method = RequestMethod.POST)
	@ResponseBody
	@RequiresAuthentication
	public Object setOrderStatus(@RequestBody JSONObject jsonData) {
		int orderID = jsonData.getInteger("orderID");
		int postStatus = jsonData.getInteger("postStatus");
		int isValid = jsonData.getInteger("isValid");
		Orders orders = ordersService.selectById(orderID);
		orders.setPostStatus(postStatus);
		orders.setIsValid(isValid);
		ordersService.updateById(orders);

		return new ResponseBean(200, "set success", JSONObject.toJSON(orders));
	}

	/**
	 * 设置订单邮寄信息
	 */
	@ApiOperation(value = "设置订单邮寄信息", notes = "需要参数：订单ID,邮寄公司,快递编号")
	@ApiImplicitParam(name = "jsonData", value = "包含元素：orderID,postCompanyName,postNumber", dataType = "JSONObject")
	@RequestMapping(value = "/setPostInfo", method = RequestMethod.POST)
	@ResponseBody
	@RequiresAuthentication
	public Object setPostInfo(@RequestBody JSONObject jsonData) {
		int orderID = jsonData.getInteger("orderID");
		String postCompanyName = jsonData.getString("postCompanyName");
		String postNumber = jsonData.getString("postNumber");
		Orders orders = ordersService.selectById(orderID);
		orders.setPostCompanyName(postCompanyName);
		orders.setPostNumber(postNumber);
		ordersService.updateById(orders);
		return new ResponseBean(200, "set success", JSONObject.toJSON(orders));
	}

	/**
	 * 订单详情
	 */
	@ApiOperation(value = "订单详情", notes = "需要参数：订单ID")
	@ApiImplicitParam(name = "orderID", value = "订单编号", dataType = "Integer")
	@RequestMapping(value = "/detail/{orderID}", method = RequestMethod.GET)
	@ResponseBody
	@RequiresAuthentication
	public Object detail(@PathVariable("orderID") Integer orderID) {
		return new ResponseBean(200, "operation success", ordersService.selectById(orderID));
	}
}
